import pyttsx3
import threading
from typing import Optional
from queue import Queue, Empty
import time


class TTSPlayer:
    """
    文本转语音播放工具类
    """
    def __init__(self):
        """
        初始化TTS引擎
        """
        try:
            self.engine = pyttsx3.init()
            # 设置语速
            self.engine.setProperty('rate', 200)
            # 设置音量
            self.engine.setProperty('volume', 0.9)
            # 设置语音（可选）
            voices = self.engine.getProperty('voices')
            # 如果有中文语音，选择中文语音
            for voice in voices:
                if 'zh' in voice.id or 'chinese' in voice.name.lower():
                    self.engine.setProperty('voice', voice.id)
                    break
            
            # 创建播报队列和线程
            self.speech_queue = Queue()
            self.is_speaking = False
            self.speech_thread = threading.Thread(target=self._speech_worker, daemon=True)
            self.speech_thread.start()
            
            # 添加去重机制
            self.last_spoken_text = ""
            self.last_spoken_time = 0
            
            # 添加锁机制防止并发问题
            self.lock = threading.Lock()
        except Exception as e:
            print(f"❌ TTS引擎初始化失败: {e}")
            self.engine = None

    def _speech_worker(self):
        """
        处理播报任务的工作线程
        """
        while True:
            try:
                # 从队列中获取播报任务
                text = self.speech_queue.get(timeout=1)
                if text is None:  # 停止信号
                    break
                    
                try:
                    self.is_speaking = True
                    self.engine.say(text)
                    self.engine.runAndWait()
                except Exception as e:
                    print(f"❌ 播报过程中出现错误: {e}")
                finally:
                    self.is_speaking = False
                    self.speech_queue.task_done()
                    
            except Empty:
                continue  # 队列超时，继续循环
            except Exception as e:
                print(f"❌ 语音工作线程错误: {e}")
                continue

    def speak(self, text: str, blocking: bool = False) -> bool:
        """
        播报文本
        
        Args:
            text: 要播报的文本
            blocking: 是否阻塞当前线程直到播报完成（注意：此参数在此实现中无效）
            
        Returns:
            bool: 播报是否成功启动
        """
        if not self.engine:
            print("❌ TTS引擎未初始化")
            return False
            
        if not text or not text.strip():
            print("❌ 播报文本为空")
            return False
            
        # 去重检查：如果与上次播报的内容相同且时间间隔小于5秒，则跳过
        current_time = time.time()
        stripped_text = text.strip()
        
        # 使用锁确保线程安全
        with self.lock:
            if stripped_text == self.last_spoken_text and (current_time - self.last_spoken_time) < 5:
                return True
                
            try:
                print(f"🤖 ：{text}")
                
                # 更新最后播报的内容和时间
                self.last_spoken_text = stripped_text
                self.last_spoken_time = current_time
                
            except Exception as e:
                print(f"❌ 文本播报失败: {e}")
                return False
        
        try:
            # 将播报任务加入队列
            self.speech_queue.put(stripped_text)  # 使用标准化后的文本
            return True
        except Exception as e:
            print(f"❌ 添加播报任务失败: {e}")
            return False

    def is_busy(self) -> bool:
        """
        检查TTS引擎是否正在播报
        
        Returns:
            bool: 是否正在播报
        """
        return self.is_speaking

    def stop(self):
        """
        停止当前播报
        """
        if self.engine:
            try:
                # 清空播报队列
                while not self.speech_queue.empty():
                    try:
                        self.speech_queue.get_nowait()
                    except Empty:
                        break
                        
                self.engine.stop()
                self.is_speaking = False
            except Exception as e:
                print(f"❌ 停止播报失败: {e}")

    def set_rate(self, rate: int):
        """
        设置语速
        
        Args:
            rate: 语速（一般在50-400之间）
        """
        if self.engine:
            self.engine.setProperty('rate', rate)

    def set_volume(self, volume: float):
        """
        设置音量
        
        Args:
            volume: 音量（0.0-1.0）
        """
        if self.engine:
            self.engine.setProperty('volume', volume)

    def set_voice(self, voice_id: str):
        """
        设置语音
        
        Args:
            voice_id: 语音ID
        """
        if self.engine:
            self.engine.setProperty('voice', voice_id)

    def get_voices(self):
        """
        获取可用的语音列表
        
        Returns:
            list: 语音列表
        """
        if self.engine:
            return self.engine.getProperty('voices')
        return []


# 全局TTS播放器实例
_tts_player: Optional[TTSPlayer] = None


def get_tts_player() -> TTSPlayer:
    """
    获取全局TTS播放器实例（单例模式）
    
    Returns:
        TTSPlayer: TTS播放器实例
    """
    global _tts_player
    if _tts_player is None:
        _tts_player = TTSPlayer()
    return _tts_player


def speak_text(text: str) -> bool:
    """
    播报文本（便捷函数）
    
    Args:
        text: 要播报的文本
        blocking: 是否阻塞当前线程直到播报完成（注意：此参数在此实现中无效）
        
    Returns:
        bool: 播报是否成功启动
    """
    try:
        import pyttsx3
        engine = pyttsx3.init()
        engine.setProperty('rate', 200)
        engine.setProperty('volume', 0.9)
        engine.say(text)
        print(f"🤖 {text}")
        engine.runAndWait()
        return True
    except Exception as e:
        print(f"❌ 语音播报失败: {text}, 错误: {e}")
        return False

if __name__ == "__main__":
    # 测试代码
    speak_text("你好，这是一个文本转语音的测试")